package completablefuture;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.concurrent.*;

/**
 * @author ZhuQi
 * @ClassName Demo2
 * @Date 2022/9/5 16:14
 * @Version 1.0
 * @Description 功能演示，减少阻塞和轮询
 */
@Slf4j
public class Demo2 {

    /**
     * 测试内容: 测试 completableFuture 回调
     * 测试结果:
     */
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 4,
                30L, TimeUnit.SECONDS, new ArrayBlockingQueue(10));
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
            log.info(Thread.currentThread().getName());
            int i = ThreadLocalRandom.current().nextInt(10);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (i > 5) {
                i = 10 / 0;
            }
            return i;
        }, executor);

        // 完成后的回调
        completableFuture.whenComplete((v, e) -> {
            if (e == null) {
                log.info("没有异常，打印值：{}", v);
            }
        });

        // 异常后的回调
        completableFuture.exceptionally((e) -> {
            e.printStackTrace();
            log.info("发生异常了 {}", e.getCause());
            return -1;
        });

        // 主线程不要立即结束，主线程结束，ForkJoinPoll 会关闭
        // TimeUnit.SECONDS.sleep(3);

        // 使用自定义线程池就不会关闭
        executor.shutdown();
    }

    /**
     * 测试内容: 测试 completableFuture 回调
     * 单元测试这里还是关闭自定义的线程池，很是奇怪，也没有研究出来为什么
     */
    @Test
    public void test() throws Exception {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 4,
                30L, TimeUnit.SECONDS, new ArrayBlockingQueue(10));
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
            log.info(Thread.currentThread().getName());
            int i = ThreadLocalRandom.current().nextInt(10);

            boolean daemon = Thread.currentThread().isDaemon();
            log.info("是否是守护线程 daemon：{}", daemon);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return i;
        }, executor);

        // 完成后的回调
        completableFuture.whenComplete((v, e) -> {
            if (e == null) {
                log.info("没有异常，打印值：{}", v);
            }
        });

        // 异常后的回调
        completableFuture.exceptionally((e) -> {
            e.printStackTrace();
            log.info("发生异常了 {}", e.getCause());
            return -1;
        });

        boolean daemon = Thread.currentThread().isDaemon();
        log.info("是否是守护线程 daemon：{}", daemon);
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement stackTraceElement : stackTrace) {
            log.info(stackTraceElement.toString());
        }
        // 主线程不要立即结束，主线程结束，ForkJoinPoll 会关闭
        // TimeUnit.SECONDS.sleep(3);

        // 使用自定义线程池就不会关闭，但是单元测试这里还是关闭了
        executor.shutdown();
    }


}
